package com.bootdo.system.service.impl;

import cn.hutool.core.util.IdUtil;
import com.bootdo.common.config.Constant;
import com.bootdo.common.dao.DictDao;
import com.bootdo.common.domain.DictDO;
import com.bootdo.common.pojo.UserReq;
import com.bootdo.common.utils.*;
import com.bootdo.system.dao.UserCodeDao;
import com.bootdo.system.dao.UserDao;
import com.bootdo.system.dao.UserRoleDao;
import com.bootdo.system.domain.UserCodeDO;
import com.bootdo.system.domain.UserDO;
import com.bootdo.system.domain.UserRoleDO;
import com.bootdo.system.service.LoginService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 前台登陆service
 *
 * @author zhouxm
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class LoginServiceImpl implements LoginService {
    @Autowired
    private UserDao userDao;

    @Autowired
    private UserCodeDao userCodeDao;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    UserRoleDao userRoleMapper;

    private UserCodeDO setUserCode(String mobile, String code) {
        Date date = new Date();
        UserCodeDO userCodeDO = new UserCodeDO();
        userCodeDO.setId(IdUtil.fastSimpleUUID());
        userCodeDO.setCode(code);
        userCodeDO.setMobile(mobile);
        userCodeDO.setSendTime(date);
        userCodeDO.setCreateTime(date);
        return userCodeDO;
    }

    @Override
    public R sendVerifyCode(String mobile) throws Exception {
        String code = MathUtils.getVerifyCode();
        //发送短信接口
        log.info("verify code: {}", code);
        R r = SendUtils.sendSms(mobile,code);
        if(!StringUtils.equals(String.valueOf(r.get("code")),"0")) {
            return r;
        }
        Long timeout = Constant.REDIS_CODE_TIMEOUT;
        boolean flag = redisUtils.set(mobile, code, timeout, TimeUnit.MINUTES);
        if (flag) {
            userCodeDao.save(setUserCode(mobile, code));
        }
        return R.ok().put("verifyCode",code);
    }

    @Override
    public boolean checkCodeUsed(String mobile, String code) throws Exception {
        UserCodeDO userCodeDO = userCodeDao.getByCodeUsed(mobile, code);
        return userCodeDO != null;
    }

    @Override
    public int updateCodeStatus(String mobile, String code) throws Exception {
        UserCodeDO userCodeDO = new UserCodeDO();
        userCodeDO.setMobile(mobile);
        userCodeDO.setCode(code);
        userCodeDO.setUpdateTime(new Date());
        userCodeDO.setIsUsed(Constant.CODE_USED);
        return userCodeDao.updateCodeStatus(userCodeDO);
    }

    @Override
    public R register(UserReq req) throws Exception {
        String mobile = req.getMobile();
        UserDO userDO = userDao.getByMobile(mobile);
        if (userDO != null) {
            // 表示用户已经存在
            return R.error("该手机号已被注册，请重新填写！");
        }
        userDO = setUserData(req);
        int count = userDao.save(userDO);
        Long userId = userDO.getUserId();
        userRoleMapper.removeByUserId(userId);
        List<UserRoleDO> list = new ArrayList<>();
        UserRoleDO ur = new UserRoleDO();
        ur.setUserId(userId);
        //普通用户
        ur.setRoleId(2l);
        list.add(ur);
        if (list.size() > 0) {
            userRoleMapper.batchSave(list);
        }
        return R.ok(userDO);
    }

    /***
     * 重置密码
     * @param req
     * @return
     */
    @Override
    public R resetPassword(UserReq req) {
        UserDO userDO = userDao.getByMobile(req.getMobile());
        if (userDO == null) {
            // 表示用户已经存在
            return R.error("该手机号未注册用户！");
        }
        userDO.setPassword(req.getPassword());
        userDao.update(userDO);
        return R.ok();
    }

    private UserDO setUserData(UserReq req) {
        UserDO userDO = new UserDO();
        userDO.setUsername(req.getUsername());
        userDO.setMobile(req.getMobile());
        userDO.setPassword(req.getPassword());
        userDO.setStatus(1);
        userDO.setGmtCreate(new Date());
        userDO.setIntegral(0l);
        userDO.setName(req.getUsername());
        userDO.setFrozenType("2");//正常
        return userDO;
    }
}
